using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.Threading;
using FE;

namespace WinFE
{
    public class WinFormsAdapter : GameAdapter
    {
        private Dictionary<Type, Color> TileColorMap = new Dictionary<Type, Color>();

        private int buttonScale = 48;
        private GameForm gf;
        public Form GameForm
        {
            get { return gf; }
        }
        public WinFormsAdapter()
        {
            TileColorMap[typeof (PlainsTile)] = Color.Green;
            TileColorMap[typeof (MountainsTile)] = Color.Chocolate;
            TileColorMap[typeof (WoodsTile)] = Color.DarkGreen;
        }

        private Button[][] gridButtons;
        private Dictionary<Button, Point> ButtonLocations = new Dictionary<Button, Point>();
        public override void PerformMapInitialize(Map map)
        {
            gf = new GameForm(this);

            gridButtons = new Button[map.Width][];
            for (int i = 0; i < map.Width; i++)
            {
                gridButtons[i] = new Button[map.Height];
                for (int j = 0; j < map.Height; j++)
                {
                    Button b = new Button();

                    b.Click += new EventHandler(buttonPress);
                    b.MouseHover += new EventHandler(buttonHover);
                    b.Size = new Size(buttonScale, buttonScale);
                    b.Location = new Point(i*buttonScale, j*buttonScale);
                    b.TextAlign = ContentAlignment.MiddleLeft;
                    b.Font = new Font("Verdana", 8, FontStyle.Bold);

                    gf.getPanel().Controls.Add(b);

                    gridButtons[i][j] = b;
                    ButtonLocations[b] = new Point(i, j);
                }
            }

            gf.SetDetailStatus("Start Battle!");

        }
        public override void PerformTurn(Player p)
        {            
            const string message = "{0}'s Turn!";
            gf.SetDetailStatus(string.Format(message, p.Name));            
        }
        public override void PerformSelect(UnitStatus unit)
        {
            const string message = "{0} is selected.";
            gf.SetDetailStatus(string.Format(message, unit.unit.Name));
        }
        public override void AddAction(GameAdapter.Actions action)
        {
            gf.ShowActions(action);
        }
        public override void ClearActions()
        {
            gf.HideActions();
        }
        public override void PerformMove (int x0, int y0, int x1, int y1)
        {
        }
        public override void PerformBattle(List<BattleResult> battleResults)
        {
            foreach (BattleResult br in battleResults)
            {
                gf.SetDetailStatus(br.ToString());
            }
        }
        public override void  ActionChoice()
        {
            //gf.ShowActions(GameAdapter.Actions.Attack, GameAdapter.Actions.Wait);                        
        }
        
        public void buttonHover(object sender, EventArgs args)
        {
            Button b = sender as Button;
            Point p = ButtonLocations[b];
            Map.MapNode mn = map[p.X, p.Y];

            string stats = string.Format(quickStatsTile, mn.tile.Name, mn.tile.Defense, mn.tile.Evasion);
            if (mn.unit != null) {
                stats += string.Format(quickStatsUnit, mn.unit.unit.Name, mn.unit.health, mn.unit.unit.HitPointValue, "1");
            }
            gf.SetQuickStatus(stats);
        }
        public void buttonPress(object sender, EventArgs args)
        {
            Button b = sender as Button;
            Point p = ButtonLocations[b];
            if (currentPlayerTurn != null)
            {
                Map.MapNode mn = map[p.X, p.Y];
                if (mn.unit != null)
                {
                    //if (mn.unit.Owner == currentPlayerTurn)
                    if (currentPlayerTurn.OwnsUnit(mn.unit))
                    {
                        if (mn.unit == CurrentUnit)
                        {
                            Game.Input(new UnitMoveInput()[p.X, p.Y]);
                        }
                        Game.Input(new UnitSelectInput()[p.X, p.Y]);
                    }
                    else
                    {
                        Game.Input(new UnitAttackInput()[p.X, p.Y]);
                    }
                }
                else
                {
                    Game.Input(new UnitMoveInput()[p.X, p.Y]);
                }
            }
        }

        public override void UpdateMap()
        {
            for (int i = 0; i < map.Width; i++)
            {
                for (int j = 0; j < map.Height; j++)
                {
                    Button b = gridButtons[i][j];

                    Map.MapNode mn = map[i, j];
                    Tile tile = mn.tile;
                    if (TileColorMap.ContainsKey(tile.GetType()))
                        b.BackColor = TileColorMap[tile.GetType()];
                    if (mn.highlightAction == Actions.Move)
                    {
                        b.BackColor = Color.Aqua;
                    }
                    else if (mn.highlightAction == Actions.Attack)
                    {
                        b.BackColor = Color.Red;
                    }
                    if (mn.unit != null)
                    {
                        b.Text = mn.unit.unit.Name.Substring(0, 3);
                    }
                    else
                    {
                        b.Text = string.Empty;
                    }
                }
            }
        }
    }
}